﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _03_Task
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Task  是异步(多线程)的一种新解决方案  
            // 异步是使用多线程来实现 

            // 程序的执行分为同步和异步两种形式 
            // 同步: 多个任务排队执行
            // 异步: 多个任务同时执行，谁执行的快谁先执行完成 

            // Task 和 Thread 的区别 
            // Task自带线程池 Thread 需要通过 ThreadPool 创建线程池

            Task task = new Task(() =>
            {
                Thread.Sleep(1000);
                // 会在线程中执行
                Console.WriteLine($"创建了一个线程线程id是：{Thread.CurrentThread.ManagedThreadId}");
                Console.WriteLine("创建了一个异步任务");
            });
            Task task1 = new Task(() =>
            {
                // 会在线程中执行
                Console.WriteLine($"创建了一个线程线程id是：{Thread.CurrentThread.ManagedThreadId}");
                Console.WriteLine("创建了一个异步任务");
            });

            task.Start(); // 启动线程 
            task1.Start();
            Console.WriteLine("123");

        }

        private void button2_Click(object sender, EventArgs e)
        {
            // new Task 和 Task.Run 的区别 
            // Task.Run 会立即调用  而 new Task 需要通过 实例对象调用 Start 方法启动
            Task t = Task.Run(() =>
            {
                Console.WriteLine("线程中的代码直接执行了");
            }); // 创建一个线程并立即执行 
        }

        private void button3_Click(object sender, EventArgs e)
        {
            // Task.Factory.StartNew 使用工厂函数方式创建 
            // Task.Factory.StartNew 和 Task.Run 创建的异步任务会立马执行 
            Task task = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("工厂函数形式，线程中的代码直接执行了");
            });
        }

        private async void button4_Click(object sender, EventArgs e)
        {
            // 在子线程中是无法更改ui的  更改ui 只能在主线程中操作 
            /*
            Task task = new Task(() =>
            {
                //Console.WriteLine("");
                Thread.Sleep(1000); // 一秒之后将label 文本改成 123
                                    //label1.Text = "123";

                // Invoke 是一个同步的方法 
                // 这个方法必须执行完成后续的代码才能执行 
                //Invoke(new Action(() =>
                //{
                //    // Invoke 中的代码会放回到主线程中执行
                //    Thread.Sleep(1000);
                //    label1.Text = "123";
                //}));

                // BeginInvoke  是一个异步的方法
                // 这个方法的执行与后面的代码是互补影响的 
                //BeginInvoke(new Action(() =>
                //{
                //     Thread.Sleep(1000);
                //     label1.Text = "123";
                // }));


                // 任何一个控件都有这个方法 
                label1.Invoke(new Action(() =>
                {
                    // Invoke 将代码放回到 主线程执行 
                    Thread.Sleep(1000);
                    label1.Text = "123";
                }));


                MessageBox.Show("123");

            });
            task.Start();
            */
            //label1.Text = "123";

            Thread thread = new Thread(() =>
            {

                Thread.Sleep(1000);
                // 在主线程更新ui 
                Invoke(new Action(() => { label1.Text = "123"; }));
                //label1.Text = "123";
            });
            thread.Start();

            /*
            
            Timer timer = new Timer();

            timer.Interval = 1000;
            timer.Start();
            timer.Tick += () => { }

            */


            
        }



        // 使用task 封装一个类似 Timer 的类 每间隔指定时间执行自定义逻辑 

    }
}
